#include <iostream>
#include <utility>
#include <memory>
#include <vector>
#include <string>

// 示例类：资源管理
class Resource {
private:
  std::string m_name_;

public:
  Resource(const std::string& name) : m_name_(name) {
    std::cout << "    创建资源: " << m_name_ << "\n";
  }

  ~Resource() {
    std::cout << "    销毁资源: " << m_name_ << "\n";
  }

  const std::string& name() const { return m_name_; }
};

void demonstrate_exchange() {
  std::cout << "  C++14 std::exchange 演示:\n\n";

  // 1. 基本用法
  std::cout << "  1. 基本用法:\n";

  int x = 10;
  int old_x = std::exchange(x, 20);
  std::cout << "    x = 10, std::exchange(x, 20)\n";
  std::cout << "    旧值: " << old_x << ", 新值: " << x << "\n";

  // 2. 原子交换语义
  std::cout << "\n  2. 原子交换语义:\n";

  std::string str = "old";
  std::string old_str = std::exchange(str, "new");
  std::cout << "    旧字符串: \"" << old_str << "\"\n";
  std::cout << "    新字符串: \"" << str << "\"\n";

  // 3. 与智能指针结合
  std::cout << "\n  3. 与智能指针结合:\n";

  auto ptr1 = std::make_unique<Resource>("Resource1");
  auto ptr2 = std::make_unique<Resource>("Resource2");

  std::cout << "    交换前:\n";
  std::cout << "      ptr1指向: " << (ptr1 ? ptr1->name() : "null") << "\n";
  std::cout << "      ptr2指向: " << (ptr2 ? ptr2->name() : "null") << "\n";

  auto old_ptr1 = std::exchange(ptr1, std::move(ptr2));
  std::cout << "    交换后:\n";
  std::cout << "      ptr1指向: " << (ptr1 ? ptr1->name() : "null") << "\n";
  std::cout << "      old_ptr1指向: " << (old_ptr1 ? old_ptr1->name() : "null") << "\n";

  // 4. 在移动构造函数中使用
  std::cout << "\n  4. 在移动构造函数中使用:\n";

  class Widget {
  private:
    std::unique_ptr<Resource> m_resource_;

  public:
    Widget(std::unique_ptr<Resource> resource)
      : m_resource_(std::move(resource)) {}

    // 移动构造函数
    Widget(Widget&& other) noexcept
      : m_resource_(std::exchange(other.m_resource_, nullptr)) {
      std::cout << "    Widget移动构造\n";
    }

    const Resource* resource() const {
      return m_resource_.get();
    }
  };

  auto res = std::make_unique<Resource>("WidgetResource");
  Widget w1(std::move(res));
  Widget w2(std::move(w1));
  std::cout << "    w2的资源: " << (w2.resource() ? w2.resource()->name() : "null") << "\n";

  // 5. 重置并获取旧值
  std::cout << "\n  5. 重置并获取旧值:\n";

  std::vector<int> vec = {1, 2, 3, 4, 5};
  std::vector<int> old_vec = std::exchange(vec, {10, 20, 30});

  std::cout << "    旧向量大小: " << old_vec.size() << "\n";
  std::cout << "    新向量大小: " << vec.size() << "\n";

  // 6. 在状态机中使用
  std::cout << "\n  6. 在状态机中使用:\n";

  enum class State { IDLE, RUNNING, PAUSED, STOPPED };
  State current_state = State::IDLE;

  auto transition = [&current_state](State new_state) {
    State old_state = std::exchange(current_state, new_state);
    std::cout << "    状态转换: ";
    switch (old_state) {
      case State::IDLE: std::cout << "IDLE"; break;
      case State::RUNNING: std::cout << "RUNNING"; break;
      case State::PAUSED: std::cout << "PAUSED"; break;
      case State::STOPPED: std::cout << "STOPPED"; break;
    }
    std::cout << " -> ";
    switch (new_state) {
      case State::IDLE: std::cout << "IDLE"; break;
      case State::RUNNING: std::cout << "RUNNING"; break;
      case State::PAUSED: std::cout << "PAUSED"; break;
      case State::STOPPED: std::cout << "STOPPED"; break;
    }
    std::cout << "\n";
    return old_state;
  };

  transition(State::RUNNING);
  transition(State::PAUSED);
  transition(State::STOPPED);

  // 7. 与optional结合
  std::cout << "\n  7. 与optional结合 (C++17风格):\n";

  // 模拟optional的行为
  class OptionalInt {
  private:
    bool m_has_value_;
    int m_value_;

  public:
    OptionalInt() : m_has_value_(false), m_value_(0) {}
    OptionalInt(int value) : m_has_value_(true), m_value_(value) {}

    int value_or(int default_value) const {
      return m_has_value_ ? m_value_ : default_value;
    }

    OptionalInt& operator=(int value) {
      m_has_value_ = true;
      m_value_ = value;
      return *this;
    }

    int exchange(int new_value) {
      int old = m_value_;
      m_value_ = new_value;
      m_has_value_ = true;
      return old;
    }
  };

  OptionalInt opt(42);
  int old_opt = opt.exchange(100);
  std::cout << "    旧值: " << old_opt << ", 新值: " << opt.value_or(0) << "\n";

  // 8. 性能优势
  std::cout << "\n  8. 性能优势:\n";

  std::cout << "    std::exchange 的优势:\n";
  std::cout << "    - 原子操作语义，避免中间状态\n";
  std::cout << "    - 简化移动语义的实现\n";
  std::cout << "    - 代码更简洁，意图更明确\n";
  std::cout << "    - 减少临时变量\n";
  std::cout << "    - 在状态转换中特别有用\n";

  // 9. 实际应用：缓存更新
  std::cout << "\n  9. 实际应用 - 缓存更新:\n";

  class Cache {
  private:
    std::string m_data_;

  public:
    std::string update(const std::string& new_data) {
      return std::exchange(m_data_, new_data);
    }

    const std::string& get() const { return m_data_; }
  };

  Cache cache;
  std::string old_data = cache.update("Data1");
  std::cout << "    旧数据: \"" << old_data << "\"\n";
  std::cout << "    当前数据: \"" << cache.get() << "\"\n";

  old_data = cache.update("Data2");
  std::cout << "    更新后旧数据: \"" << old_data << "\"\n";
  std::cout << "    当前数据: \"" << cache.get() << "\"\n";
}

